import { useState, useEffect } from 'react'
import { message, Select } from 'antd';

import { SelectOption as RemoteSelect } from '../RemoteSelect'
import styles from './index.module.sass';

const { Option } = Select;

/**联动选择器的数量枚举 */
export const enum SelectNumber {
    // 显示两个选择器
    Two,
    // 显示三个选择器
    Three,
}

interface SelectOption extends RemoteSelect {
    /**下一级选择器数据 */
    children?: SelectOption[]
}

interface Props {
    /**联动选择器请求后端数据的函数 */
    remote: Function

    value?: any

    /**联动选择器的数量 */
    number?: SelectNumber

    /**用于触发表单值的更新 */
    onChange?: Function
}

const CoordinateSelect: React.FC<Props> = ({
    remote,
    value,
    number,
    onChange
}) => {
    console.debug('CoordinateSelect value', value);

    /**选择框选中的数据 */
    const [firstSelectValue, setFirstSelectValue] = useState('');
    const [secondSelectValue, setSecondSelectValue] = useState('');
    const [thirdSelectValue, setThirdSelectValue] = useState('');
    /**选择框数据列表 */
    const [firstSelect, setFirstSelect] = useState<SelectOption[]>([]);
    const [secondSelect, setSecondSelect] = useState<SelectOption[]>([]);
    const [thirdSelect, setThirdSelect] = useState<SelectOption[]>([]);
    /**初始化数据标记 */
    const [initList, setInitList] = useState([]);
    const [initFlag, setInitFlag] = useState(false);

    const [className] = useState(() =>
        number === SelectNumber.Two ? styles.twoSelectors : styles.threeSelectors);

    useEffect(() => {
        async function main() {
            if(!_.isString(value)){
                try {
                    const cityList: SelectOption[] = await remote();
                    if (!_.isEmpty(cityList)) {
                        setFirstSelect(cityList);
                        if (_.isArray(value)) {
                            setInitList(value);
                            setInitFlag(true);
                            setFirstSelectValue(value[0]);
                        } else if (_.isUndefined(value)) {
                            setFirstSelectValue(cityList[0].value);
                        }
                    }
                } catch (error) {
                    console.error('联动下拉数据加载异常', error);
                    message.error('联动下拉数据加载异常');
                }
            }
        }
        main()
    }, [remote, value])

    useEffect(() => {
        const selectList: string[] = [firstSelectValue, secondSelectValue, thirdSelectValue];
        onChange && onChange(JSON.stringify(selectList));
    }, [firstSelectValue, secondSelectValue, thirdSelectValue, onChange]);

    /**选择框的联动效果 */
    useEffect(() => {
        if (!_.isEmpty(firstSelect)) {
            handSelect(firstSelectValue, firstSelect, setSecondSelect, setSecondSelectValue);
        }
    }, [firstSelect, firstSelectValue]);

    useEffect(() => {
        if (!_.isEmpty(secondSelect)) {
            handSelect(secondSelectValue, secondSelect, setThirdSelect, setThirdSelectValue);
        }
    }, [secondSelect, secondSelectValue]);

    /**设置选择框的默认值 */
    useEffect(() => {
        if (initFlag) {
            if (!_.isEmpty(thirdSelect)) {
                setThirdSelectValue(initList[2]);
                setInitFlag(false);
            } else if (!_.isEmpty(secondSelect)) {
                setSecondSelectValue(initList[1]);
                if (number === SelectNumber.Two) {
                    setInitFlag(false);
                }
            }
        }
    }, [secondSelect, thirdSelect, initList, initFlag, number]);

    /**
     * 当前选择器选中后，设置下一级选择器数据和默认显示内容
     * @param value 当前选择器选中的数据值
     * @param dataList 当前选择器中的数据列表，列表中包含下一级选择器数据（含有 children 字段）
     * @param setSelectData 设置下一级选择器数据列表的函数
     * @param setSelectValue 设置下一级选择器默认显示内容的函数
     */
    const handSelect = (
        value: string | number,
        dataList: SelectOption[],
        setSelectData: Function,
        setSelectValue: Function,
    ) => {
        const list: any = dataList.filter((item: any) => item.value === value);
        const selectList = _.has(list[0], 'children') ? list[0]['children'] : [];
        setSelectData(selectList);
        if (selectList.length > 0) {
            setSelectValue(selectList[0]['value']);
        }
    }

    const selectRender = (selectList: SelectOption[]) => (
        selectList.map(({ name, value }: SelectOption) =>
            <Option value={value} key={value}>{name}</Option>
        )
    )

    return (
        <div className={styles.selectBox}>
            <Select
                value={firstSelectValue}
                onChange={value => {
                    setFirstSelectValue(value);
                    handSelect(value, firstSelect, setSecondSelect, setSecondSelectValue);
                }}
            >
                {selectRender(firstSelect)}
            </Select>
            <Select
                className={className}
                value={secondSelectValue}
                onChange={value => {
                    setSecondSelectValue(value);
                    handSelect(value, secondSelect, setThirdSelect, setThirdSelectValue);
                }}
            >
                {selectRender(secondSelect)}
            </Select>
            {
                number !== SelectNumber.Two &&
                <Select
                    className={styles.threeSelectors}
                    value={thirdSelectValue}
                    onChange={value => setThirdSelectValue(value)}
                >
                    {selectRender(thirdSelect)}
                </Select>
            }
        </div>
    )
}

export default CoordinateSelect;